package com.fly.hello.web.async;

import java.util.concurrent.Callable;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.WebAsyncTask;

import io.swagger.annotations.Api;

@Controller
@Api(tags = "callable异步")
@RequestMapping("/async/callable")
public class CallableController
{
    @ResponseBody
    @GetMapping("/response-body")
    public Callable<String> callable()
    {
        return new Callable<String>()
        {
            @Override
            public String call()
                throws Exception
            {
                Thread.sleep(2000);
                return "Callable result";
            }
        };
    }
    
    @GetMapping("/view")
    public Callable<String> callableWithView(final Model model)
    {
        return () -> {
            Thread.sleep(2000);
            model.addAttribute("foo", "bar");
            model.addAttribute("fruit", "apple");
            return "views/html";
        };
    }
    
    @ResponseBody
    @GetMapping("/exception")
    public Callable<String> callableWithException(final @RequestParam(required = false, defaultValue = "true") boolean handled)
    {
        return () -> {
            Thread.sleep(2000);
            if (handled)
            {
                // see handleException method further below
                throw new IllegalStateException("Callable error");
            }
            else
            {
                throw new IllegalArgumentException("Callable error");
            }
        };
    }
    
    @ResponseBody
    @GetMapping("/custom-timeout-handling")
    public WebAsyncTask<String> callableWithCustomTimeoutHandling()
    {
        Callable<String> callable = () -> {
            Thread.sleep(2000);
            return "Callable result";
        };
        return new WebAsyncTask<>(1000, callable);
    }
    
    @ResponseBody
    @ExceptionHandler
    public String handleException(IllegalStateException ex)
    {
        return "Handled exception: " + ex.getMessage();
    }
}
